import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Random;

public class LifeChess {
    protected int SIZE = 20000; // 棋盘大小
    protected int GENERATIONS = 3; // 代数
    public int[][] board = new int[SIZE][SIZE];
    protected String str;
    protected int len;
    //初始化棋盘
//    public void initializeBoard() {
//        Random random = new Random();
//        for (int i = 0; i < this.SIZE; i++) {
//            for (int j = 0; j < this.SIZE; j++) {
//                this.board[i][j] = random.nextInt(2); // 随机生成0或1
//            }
//        }
//        printBoard(this.board);
//    }

    public void initializeBoardfromTxt(String fileName) throws IOException {
        Path path = Paths.get("test/"+fileName);
        String data = Files.readString(path);
        //System.out.println(data.length());
        for (int j = 0; j < data.length(); j++) {
            int k = j /SIZE;
            int l = j % SIZE;
            this.board[k][l] = data.charAt(j)-'0';
        }
        //printBoard(this.board);
    }

    public void getRes(String fileName) throws IOException {
        Path path = Paths.get("test/"+fileName);
        this.str = Files.readString(path);
    }
    // 运行生命游戏
    public void runGameOfLife() throws IOException {
        while (!checkRes()) {
            this.board = nextGeneration(this.board);
            if (checkRes()) {
                printBoard(this.board);
                Path outputPath = Paths.get("test/res.txt");
                Files.write(outputPath, Arrays.deepToString(this.board).getBytes());
            }
        }
        //printBoard(this.board);
    }

    public int[][] nextGeneration(int[][] currentBoard) {
        int[][] newBoard = new int[this.SIZE][this.SIZE];
        //迭代
        for (int i = 0; i < this.SIZE; i++) {
            for (int j = 0; j < this.SIZE; j++) {
                int alivenbCells = countAliveNeighbors(currentBoard, i, j);

                if (currentBoard[i][j] == 1) {
                    // 规则1和规则2
                    newBoard[i][j] = (alivenbCells == 2 || alivenbCells == 3) ? 1 : 0;
                } else {
                    // 规则3
                    newBoard[i][j] = (alivenbCells == 3) ? 1 : 0;
                }
            }
        }
        //printBoard(newBoard);
        return newBoard;
    }

    // 计算某细胞周围的状态为生的邻居细胞数量
    public int countAliveNeighbors(int[][] board, int x, int y) {
        int count = 0;
        for (int i = -1; i <= 1; i++) {
            for (int j = -1; j <= 1; j++) {
                if (i == 0 && j == 0) continue; // 自身不算
                int nx = x + i;
                int ny = y + j;
                if (nx >= 0 && nx < this.SIZE && ny >= 0 && ny < this.SIZE) {
                    count += board[nx][ny];
                }
            }
        }
        return count;
    }
    //打印棋盘
    public void printBoard(int[][] board) {
            for (int i = 0; i < this.SIZE; i++) {
                for (int j = 0; j < this.SIZE; j++) {
                    System.out.print(board[i][j]);
                }
                System.out.println();
            }
            System.out.println();
    }
    public boolean checkRes() {
        int k = 0;
        for (int i = 0; i < this.SIZE; i++) {
            for (int j = 0; j < this.SIZE; j++) {
                if(this.board[i][j] != this.str.charAt(k)-'0') {return false;}
                k++;
            }
        }
        return true;
    }
    public LifeChess() {}
    public void setSIZE(int size) {
        this.SIZE = size;
    }
    public int getSIZE() {
        return SIZE;
    }
    public void setGENERATIONS(int GENERATIONS) {
        this.GENERATIONS = GENERATIONS;
    }
    public int getGENERATIONS() {
        return GENERATIONS;
    }

    public int[][] getBoard() {
        return board;
    }
}
